#include "triangulo.h"
#include <unistd.h>

int triangulo::countId=1;
triangulo::triangulo(float a,float b,float c,float d,float e,float f,int i){

    vertices[0][0]=a;
    vertices[0][1]=b;
    vertices[1][0]=c;
    vertices[1][1]=d;
    vertices[2][0]=e;
    vertices[2][1]=f;

    vecino1=0;
    vecino2=0;
    vecino3=0;
    id=i;
}
triangulo::triangulo(float a,float b,float c,float d,float e,float f){

    vertices[0][0]=a;
    vertices[0][1]=b;
    vertices[1][0]=c;
    vertices[1][1]=d;
    vertices[2][0]=e;
    vertices[2][1]=f;

    vecino1=0;
    vecino2=0;
    vecino3=0;
    id=countId;
    countId++;
    id1=0;
    id2=0;
    id3=0;

    owner=0;
}


float* triangulo::getVerticesByLado(int i){
    float* a=new float[4];
    if(i==1){a[0]=vertices[0][0];
            a[1]=vertices[0][1];
            a[2]=vertices[1][0];
            a[3]=vertices[1][1];
    }
    if(i==2){a[0]=vertices[1][0];
            a[1]=vertices[1][1];
            a[2]=vertices[2][0];
            a[3]=vertices[2][1];}
    if(i==3){a[0]=vertices[2][0];
            a[1]=vertices[2][1];
            a[2]=vertices[0][0];
            a[3]=vertices[0][1];}
    return a;

}


triangulo::triangulo* copiar(triangulo* t){
  triangulo* t2;
  t2=(triangulo*)malloc(sizeof(triangulo));
  t2->vertices[0][0]=t->getvertices(1,0);
  t2->vertices[0][1]=t->getvertices(1,1);
  t2->vertices[1][0]=t->getvertices(1,0);
  t2->vertices[1][1]=t->getvertices(1,1);
  t2->vertices[2][0]=t->getvertices(2,0);
  t2->vertices[2][1]=t->getvertices(2,1);
  t2->setVecino(t->getVecino(1),1);
  t2->setVecino(t->getVecino(2),2);
  t2->setVecino(t->getVecino(3),3);
  return t2;





}

void triangulo::setVecino(triangulo* t,int i){
    if(i==1){
 vecino1=t;
 if(t!=0)
 id1=t->id;}
    else if(i==2){
 vecino2=t;
  if(t!=0)
id2=t->id;}
      else if(i==3){
 vecino3=t;
  if(t!=0)
id3=t->id;}
  }



triangulo* triangulo::getVecino(int i){
     if(i==1){
       return vecino1;}
     if(i==2){
 return vecino2;}
      if(i==3){
 return vecino3;}
      return vecino3;
}
void triangulo::setColor(float a,float b,float c){
    color[0]=a;
    color[1]=b;
    color[2] =c;

}

void triangulo::dibujar(){
glPushMatrix();
 glColor3f (color[0],color[1],color[2]);
    glBegin( GL_TRIANGLES );
                glVertex2f( vertices[0][0], vertices[0][1] );
                glVertex2f(vertices[1][0], vertices[1][1] );
                glVertex2f( vertices[2][0],vertices[2][1]  );

     glEnd();

  glPopMatrix();
}
int triangulo::ladoMayor(){


   float d1= sqrt(pow(vertices[0][0]-vertices[1][0],2)+pow(vertices[0][1]-vertices[1][1],2));
   float d2=sqrt(pow(vertices[1][0]-vertices[2][0],2)+pow(vertices[1][1]-vertices[2][1],2));
   float d3=sqrt(pow(vertices[2][0]-vertices[0][0],2)+pow(vertices[2][1]-vertices[0][1],2));

   if(d1>d2 && d1>d3) return 1;
   if(d2>d3)        return 2;
   else  return 3;
}


float triangulo::getvertices(int x, int y){
    return vertices[x][y];
}
 int triangulo::getLadoByVecino(triangulo* i){
 if(vecino1==i){return 1;}
 else if(vecino2==i){return 2;}
 else if(vecino3==i){return 3;}
 return 0;

 }
 triangulo* triangulo::getVecinoByLado(int i){
 if(i==1){return vecino1;}
 else if(i==2){return vecino2;}
 else if(i==3){return vecino3;}
 return 0;

 }

 triangulo** triangulo::partir(){
triangulo** res=(triangulo**)malloc(sizeof(triangulo*)*2);
 if(ladoMayor()==1){res[0]= new triangulo(getvertices(0,0),getvertices(0,1),getvertices(2,0),getvertices(2,1),
                                        (getvertices(1,0)+getvertices(0,0))/2,(getvertices(1,1)+getvertices(0,1))/2);


                   res[1]= new triangulo(getvertices(1,0),getvertices(1,1),getvertices(2,0),getvertices(2,1),
                                         (getvertices(1,0)+getvertices(0,0))/2,(getvertices(1,1)+getvertices(0,1))/2);
                     res[0]->setVecino(getVecino(3),1);
                     if(getVecino(3)!=0) getVecino(3)->setVecino(res[0],getVecino(3)->getLadoByVecino(this));
                     res[0]->setVecino(res[1],2);
                     res[0]->setVecino(getVecinoByLado( ladoMayor()),3);



                     res[1]->setVecino(getVecino(2),1);
                      if(getVecino(2)!=0) getVecino(2)->setVecino(res[1],getVecino(2)->getLadoByVecino(this));
                     res[1]->setVecino(res[0],2);
                     res[1]->setVecino(getVecinoByLado( ladoMayor()),3);}

  if(ladoMayor()==2){res[0]= new triangulo(getvertices(0,0),getvertices(0,1),getvertices(2,0),getvertices(2,1),
                                        (getvertices(2,0)+getvertices(1,0))/2,(getvertices(2,1)+getvertices(1,1))/2);
                   res[1]= new triangulo(getvertices(0,0),getvertices(0,1),getvertices(1,0),getvertices(1,1),
                                         (getvertices(2,0)+getvertices(1,0))/2,(getvertices(2,1)+getvertices(1,1))/2);

                     res[0]->setVecino(getVecino(3),1);
                     if(getVecino(3)!=0) getVecino(3)->setVecino(res[0],getVecino(3)->getLadoByVecino(this));
                     res[0]->setVecino(getVecinoByLado( ladoMayor()),2);
                     res[0]->setVecino(res[1],3);

                     res[1]->setVecino(getVecino(1),1);
                     if(getVecino(1)!=0) getVecino(1)->setVecino(res[1],getVecino(1)->getLadoByVecino(this));
                     res[1]->setVecino(getVecinoByLado( ladoMayor()),2);
                     res[1]->setVecino(res[0],3);

               }
  if(ladoMayor()==3){res[0]= new triangulo(getvertices(1,0),getvertices(1,1),getvertices(0,0),getvertices(0,1),
                                        (getvertices(2,0)+getvertices(0,0))/2,(getvertices(2,1)+getvertices(0,1))/2);
                   res[1]= new triangulo(getvertices(1,0),getvertices(1,1),getvertices(2,0),getvertices(2,1),
                                         (getvertices(2,0)+getvertices(0,0))/2,(getvertices(2,1)+getvertices(0,1))/2);

                   res[0]->setVecino(getVecino(1),1);
                    if(getVecino(1)!=0) getVecino(1)->setVecino(res[0],getVecino(1)->getLadoByVecino(this));
                     res[0]->setVecino(getVecinoByLado( ladoMayor()),2);
                     res[0]->setVecino(res[1],3);

                     res[1]->setVecino(getVecino(2),1);
                      if(getVecino(2)!=0) getVecino(2)->setVecino(res[1],getVecino(2)->getLadoByVecino(this));
                     res[1]->setVecino(getVecinoByLado( ladoMayor()),2);
                     res[1]->setVecino(res[0],3);}
  res[0]->setColor(((float)(rand()%6))/10,((float)(rand()%6))/10,((float)(rand()%6))/10);
  res[1]->setColor(((float)(rand()%6))/10,((float)(rand()%6))/10,((float)(rand()%6))/10);
  /*res[0]->dibujar();
  res[1]->dibujar();*/
return res;








 }
 bool triangulo::isVecino(triangulo* t){
     int i=0;
    
    if(getvertices(0,0)==t->getvertices(0,0) && getvertices(0,1)==t->getvertices(0,1)) i++;
    if(getvertices(0,0)==t->getvertices(1,0) && getvertices(0,1)==t->getvertices(1,1)) i++;
    if(getvertices(0,0)==t->getvertices(2,0) && getvertices(0,1)==t->getvertices(2,1)) i++;

    if(getvertices(1,0)==t->getvertices(0,0) && getvertices(1,1)==t->getvertices(0,1)) i++;
    if(getvertices(1,0)==t->getvertices(1,0) && getvertices(1,1)==t->getvertices(1,1)) i++;
    if(getvertices(1,0)==t->getvertices(2,0) && getvertices(1,1)==t->getvertices(2,1)) i++;

    if(getvertices(2,0)==t->getvertices(0,0) && getvertices(2,1)==t->getvertices(0,1)) i++;
    if(getvertices(2,0)==t->getvertices(1,0) && getvertices(2,1)==t->getvertices(1,1)) i++;
    if(getvertices(2,0)==t->getvertices(2,0) && getvertices(2,1)==t->getvertices(2,1)) i++;

    if(i==2)return true;
    else return false;

 }

 int triangulo::lepp(PilaT* p, pilaSend* ps){
     triangulo** res1;//=(triangulo**)malloc(sizeof(triangulo*)*2);
    triangulo** res2;//=(triangulo**)malloc(sizeof(triangulo*)*2);
     //if(valido==0){std::cout << "LEPPP"<<  "leep 0"  <<"eso\n"; return 1; }
     //valido=0;
    triangulo* vecinoLado=getVecinoByLado(ladoMayor());



    /* si el vecino es nulo*/
    if(vecinoLado==0){

       ps->add( getVerticesByLado(ladoMayor()));
       //printf(" vertice 1 %f %f %f %f\n", getVerticesByLado(ladoMayor())[0],getVerticesByLado(ladoMayor())[1],getVerticesByLado(ladoMayor())[2],getVerticesByLado(ladoMayor())[3]);
       res1=partir();
       p->add(res1[0]);
       p->add(res1[1]);
       p->remove(this);
       free(res1);

      // valido=0;
    return 1;}
    /*si el lado mayor del vecino es mi lado mayor*/
     else if((vecinoLado->getVecinoByLado(vecinoLado->ladoMayor()))==this){
         res1=partir();
         res2=vecinoLado->partir();
         res1[0]->getLadoByVecino(vecinoLado);
         res1[1]->getLadoByVecino(vecinoLado);
         if(res1[0]->isVecino(res2[0])){
         res1[0]->setVecino(res2[0], res1[0]->getLadoByVecino(vecinoLado));
         res2[0]->setVecino(res1[0], res2[0]->getLadoByVecino(this));
         res1[1]->setVecino(res2[1], res1[1]->getLadoByVecino(vecinoLado));
         res2[1]->setVecino(res1[1], res2[1]->getLadoByVecino(this)); }
         else{
         res1[1]->setVecino(res2[0], res1[1]->getLadoByVecino(vecinoLado));
         res2[1]->setVecino(res1[0], res2[1]->getLadoByVecino(this));
         res1[0]->setVecino(res2[1], res1[0]->getLadoByVecino(vecinoLado));
         res2[0]->setVecino(res1[1], res2[0]->getLadoByVecino(this));
         }

        p->add(res1[0]);
         p->add(res1[1]);
          p->add(res2[0]);
           p->add(res2[1]);
   free(res1);
     free(res2);
     p->remove(vecinoLado);
     p->remove(this);
        return 1;}

     else{ vecinoLado->lepp(p,ps);
            lepp(p,ps);
      return 1;}
     }
int igual(float a,float b){
    float e=0.0001;
    if((a-b)<e && (a-b)>-e){
        return 1;}
    return 0;
}

int triangulo::solveT(float* p1){
    float* mitad=mitadlados();
    float e=0.0001;
 //   printf(" p1 %f %f\n", *p1,*(p1+1));
    /*if((abs(mitad[0]-p1[0])+abs(mitad[1]-p1[1]))<e){
        printf("error %f\n",(mitad[0]-p1[0])+(mitad[1]-p1[1]));
        printf(" mitad %f %f\n", *mitad,*(mitad+1));
        return 1;}
    if((abs(mitad[2]-p1[0])+abs(mitad[3]-p1[1]))<e){
        printf("error %f\n",(mitad[2]-p1[0])+(mitad[3]-p1[1]));
        printf(" mitad %f %f\n", *(mitad+2),*(mitad+3));
        return 2;}
    if((abs(mitad[4]-p1[0])+abs(mitad[5]-p1[1]))<e){
        printf("error %f\n",abs((mitad[4]-p1[0])+(mitad[5]-p1[1])));
        printf(" mitad %f %f\n", *(mitad+4),*(mitad+5));
        return 3;}*/
        if(igual(mitad[0],p1[0]) && igual(mitad[1],p1[1])){
                return 2;}
        if(igual(mitad[2],p1[0]) && igual(mitad[3],p1[1])){
                return 2;}
        if(igual(mitad[4],p1[0]) && igual(mitad[5],p1[1])){
                return 3;}
return 0;
}

float* triangulo::mitadlados(){
    float* res=(float *)malloc(sizeof(float)*6);
    res[0]=(getvertices(0,0)+getvertices(1,0))/2;
    res[1]=(getvertices(0,1)+getvertices(1,1))/2;

    res[2]=(getvertices(1,0)+getvertices(2,0))/2;
    res[3]=(getvertices(1,1)+getvertices(2,1))/2;

    res[4]=(getvertices(2,0)+getvertices(0,0))/2;
    res[5]=(getvertices(2,1)+getvertices(0,1))/2;
    return res;
}
void triangulo::refinarBypunto(PilaT* p,pilaSend* ps,float* p1){
    lepp(p,ps);
    p->recibirPunto(ps, p1);
}





